gitlab.com/SiaPrime/SiaPrime@v1.4.1/doc/Contract Recovery.md (about) 1 # File Contract Recovery 2 3 This document lays out the design for file contract recovery using file 4 contract identifiers. These identifiers are used to identify ones contracts on 5 the blockchain and to figure out what host the contract was formed with. So renters 6 can recognize a contract as their own simply by knowing their own wallet seed. 7 8 ## Deriving the contract identifier from the wallet seed 9 This section explains the multi-step process of deriving the identifier from 10 the wallet seed. 11 12 #### Renter Seed and Ephemeral Renter Seed 13 14 From the wallet sed we derive a renter seed by combining it with a specifier. 15 In the following pseudo-code `H` refers to hashing the input using the Blake2B 16 hashing algorithm. 17 ``` 18 renterSeed := H(walletSeed || "renter") 19 ``` 20 For additional security we don't use the renterSeed directly but we hash it again 21 with the `windowStart` field of the contract divided by 1000. That way we get an 22 ephemeral seed which changes every 1000 blocks and even if we hand it out to a 23 third party explorer, we don't reveal too much information. 24 ``` 25 ephemeralRenterSeed := H(renterSeed || windowStart / 1000) 26 ``` 27 28 #### Identifier Seed (32 bytes) 29 The identifier seed is the seed we use to create the identifiers we put into the 30 arbitrary data of file contract transactions. It can be handed out to third party 31 to give them read access to the contracts being created by a specific renter. 32 ``` 33 fileContractIdentifierSeed := H(ephemeralRenterSeed || "identifier_seed") 34 ``` 35 36 #### Secret Key Seed (32 bytes) 37 The secret key seed is the seed we use to create secret keys for file contracts 38 which are used to sign revisions. Giving away this seed allows someone to actually 39 use the contracts derived from it. 40 ``` 41 fileContractSecretKeySeed := H(ephemeralRenterSeed || "secret_key_seed") 42 ``` 43 44 #### Signing Key Seed (32 bytes) 45 The signing key seed is used to derive signing keys which are used to sign the 46 identifiers themselves. This allows us to give away the identifier seed without 47 allowing a third party to trick us by creating contracts and using our identifier 48 seed to make us believe we created that contract ourselves. 49 ``` 50 fileContractSigningKeySeed := H(ephemeralRenterSeed || "signing_key_seed") 51 ``` 52 53 #### Generating the identifier and keys 54 The identifier, secret key and signing key can be generated simply by using the 55 corresponding seed and the `SiacoinOutputID` that is spent by the first input of 56 the transaction that contains the file contract. 57 ``` 58 fileContractIdentifier := H(fileContractIdentifierSeed || firstInputToFileContract) 59 60 fileContractSecretKey := H(fileContractSecretKeySeed || firstInputToFileContract) 61 62 fileContractSigningKeyPart1 := H(fileContractSigningKeySeed || firstInputToFileContract || 0) 63 fileContractSigningKeyPart2 := H(fileContractSigningKeySeed || firstInputToFileContract || 1) 64 fileContractSigningKey := fileContractSigningKeyPart1 || fileContractSigningKeyPart2 65 ``` 66 The fileContractSigningKey is generated a bit differently since we need 64 bytes 67 instead of 32 bytes of entropy for Threefish. 68 69 #### Creating the final, signed identifier 70 The final, signed identifier has a length of 80 bytes and consists of three parts. 71 72 [0:16] - the file contract identifier prefix for the arbitrary data 73 74 [16:48] - the fileContractIdentifier 75 76 [48:80] - a signature created by encrypting the identifier using Threefish. 77 The 32 byte identifier is first padded with zeros to match the Threefish blocksize 78 of 64 bytes. Then it is encrypted and the first 32 bytes of the ciphertext are 79 used as the signature. 80 81 To make sure that we know to which host we can go to recover a specific contract, 82 we also append the Threefish-encrypted public key of the host to the arbitrary 83 data of the transaction. 84 85 ## Contract Recovery 86 87 Recovering a contract is relatively straightforward. 88 89 1. Check that a contract has the correct arbitrary data prefix 90 2. Generate the identifier and see if it matches 91 3. Verify that the signature of the identifier also matches 92 4. Get the latest revision of the contract from the host 93 5. Use that revision to pay the host for providing the merkle roots of the uploaded sectors 94